import json
import re

from django import http
from django.contrib import messages
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.mixins import LoginRequiredMixin
from django.core.paginator import Paginator, EmptyPage
from django.http import HttpResponse
from django.shortcuts import render, redirect, reverse
from django.views import View
from django_redis import get_redis_connection
from pymysql import DatabaseError
from rest_framework.views import APIView

from apps.orders.models import OrderInfo, OrderGoods
from apps.shoppingcart.urils import merge_cart_cookie_to_redis
from apps.users.models import User, Address
from utils import constants
from utils.geetest import GeetestLib
from utils.push_image import storage
from utils.response_code import RETCODE

pc_geetest_id = '239d43a905bd9289175183296255b2bd'
pc_geetest_key = '23b7d0abf8398637bba28d7d015d6bde'


class LoginView(View):
    def get(self, request):
        return render(request, 'login.html')

    def post(self, request):

        # 获取用户数据
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username)
        print(password)
        print(type(username))
        print(type(password))
        # 判断用户信息
        if not all([username, password]):
            messages.success(request, "缺少参数")
            return render(request, 'login.html')
        # 判断用户名是否符合要求
        if not re.match(r'^1[3-9]\d{9}$', username):
            messages.success(request, "用户名不符合要求")
            return render(request, 'login.html')
        # 判断密码是否符合要求
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            messages.success(request, "密码须为8-20位")
            return render(request, 'login.html')
        print('============================1======================')
        # 查询数据是否正确
        user = authenticate(mobile=username, password=password)
        if not user:
            messages.success(request, "用户名或密码错误")
            return render(request, 'login.html')

        # 状态保持
        login(request, user)
        print('--------------------------2-------------------------')
        next = request.GET.get('next')
        if next:
            response = redirect(next)
        else:
            # 返回主页面
            response = redirect(reverse('index:index'))
        # 合并购物车
        response = merge_cart_cookie_to_redis(request=request, user=user, response=response)
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)
        return response


class RegisterView(View):
    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):
        username = request.POST.get('user')
        mobile = request.POST.get('mobile')
        email = request.POST.get('email')
        password = request.POST.get('password')
        password2 = request.POST.get('password1')

        if not all([username, mobile, email, password, password2]):
            messages.success(request, "请补充数据")
            return render(request, 'register.html')
        # 判断用户名是否符合
        if not re.match(r'^[a-zA-Z0-9_]{5,10}$', username):
            messages.success(request, "用户名须为5-10位")
            return render(request, 'register.html')
        # 判断用户邮箱
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            messages.success(request, "邮箱格式错误")
            return render(request, 'register.html')
        # 判断密码是否正确
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            messages.success(request, "密码须为8-20位")
            return render(request, 'register.html')
        # 判断两次密码是否一致
        if password != password2:
            messages.success(request, "两次密码不一致")
            return render(request, 'register.html')
        # 判断手机号是否符合要求
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            messages.success(request, "密码须为8-20位")
            return render(request, 'register.html')

        try:
            if User.objects.filter(mobile=mobile):
                messages.success(request, "此手机已被注册，换个试试")
                return render(request, 'register.html')
        except User.DoesNotExist as r:
            print(r)
            messages.success(request, "手机错误")
            return render(request, 'register.html')
        try:
            if User.objects.filter(email=email):
                messages.success(request, "此邮箱已被注册")
                return render(request, 'register.html')
        except User.DoesNotExist as r:
            messages.success(request, "此邮箱错误")
            return render(request, 'register.html')
        # 赋值字段
        try:
            user = User.objects.create_user(username=username, password=password, mobile=mobile, email=email)
        except DatabaseError:
            return render(request, 'register.html', {'register_errmsg': '注册失败'})
        login(request, user)

        response = redirect(reverse('index:index'))
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)
        return response


class LogoutView(View):
    """退出登录页面"""

    def get(self, request):
        logout(request)
        response = redirect(reverse('index:index'))
        response.delete_cookie('username')
        return response


class MyCenterView(LoginRequiredMixin, View):
    """用户中心"""

    def get(self, request):
        print(request.user.username)
        context = {
            'username': request.user.username,
            'mobile': request.user.mobile,
            'user_image': request.user.image,

        }
        return render(request, 'my_center.html', context=context)


class My_mygrxx(LoginRequiredMixin, View):
    """用户详情页面"""

    def get(self, request):

        content = {
            'username': request.user.username,
            'birth_date': request.user.birth_date,
            'gender': request.user.gender,
            'user_image': request.user.image,
        }
        print("8888888")
        print(request.user.image)
        return render(request, 'mygrxx.html', content)

    def post(self, request):
        # 获取用户信息
        username = request.POST.get('username')
        birth_date = request.POST.get('date')
        gender = request.POST.get('gender')
        image = request.FILES.get('avatar')
        print(username, birth_date, gender, image, '===============')
        if image:
            # 将图片上传到七牛云
            image_data = image.read()
            file_name = storage(image_data)
            # 将七牛云返回的图片名字拼接成url存储到数据库
            new_image_url = "http://q2fjkbwyv.bkt.clouddn.com/" + file_name
            try:
                User.objects.update(image=new_image_url)
            except DatabaseError:
                messages.success(request, "添加头像失败, 请重试")
                return render(request, 'mygrxx.html')
            return redirect(reverse("users:my_mygrxx"))
        else:
            if not all([username, birth_date, gender]):
                messages.success(request, "缺少参数")
                return redirect('users:my_mygrxx')
            if not re.match(r'^[a-zA-Z0-9_]{5,10}$', username):
                messages.success(request, "用户名不符合要求")
                return redirect('users:my_mygrxx')


            try:
                User.objects.update(username=username, birth_date=birth_date, gender=gender)
            except DatabaseError:
                messages.success(request, "添加失败, 请重试")
                return redirect('users:my_mygrxx')

        return redirect('users:my_mygrxx')


class PasswordView(LoginRequiredMixin, View):
    """修改密码"""

    def get(self, request):

        content = {
            'username': request.user.username,
            'user_image': request.user.image,
        }
        return render(request, "password.html", content)

    def post(self, request):
        # 获取用户数据
        old_password = request.POST.get('old_password')
        new_password1 = request.POST.get("password1")
        new_password2 = request.POST.get("password2")
        # 进行数据判断
        if not all([old_password, new_password1, new_password1]):
            messages.success(request, "缺少参数")
            return redirect('users:password')
        if not re.match(r"[a-zA-Z0-9]{8,20}", new_password1):
            messages.success(request, "密码格式错误")
            return redirect('users:password')
        if new_password1 != new_password2:
            messages.success(request, "两次密码输入不正确")
            return redirect('users:password')
        # 3.检验旧密码是否正确
        if not request.user.check_password(old_password):
            messages.success(request, "原始密码错误")
            return redirect('users:password')

        # 4.更新新密码
        try:
            request.user.set_password(new_password1)
            request.user.save()
        except Exception as e:
            messages.success(request, "修改密码失败")
            return redirect('users:password')

        # 5.退出登陆,删除登陆信息
        logout(request)
        response = redirect(reverse('users:login'))
        response.delete_cookie('username')
        return response


class AddressView(LoginRequiredMixin, View):
    """添加地址"""

    def get(self, request):

        addresses = Address.objects.filter(user=request.user, is_deleted=False)
        # print(addresses)
        content = {
            'username': request.user.username,
            'user_image': request.user.image,
            'address': addresses,
            'default_address_id': request.user.default_address_id,
        }
        print(content, '----------------000000000--------------')
        return render(request, "address.html", content)

    def post(self, request):

        username = request.POST.get('username')
        mobile = request.POST.get('mobile')
        place = request.POST.get('address')
        detail = request.POST.get('detail')
        postcode = request.POST.get('portcode')
        if not all([username, mobile, place, detail]):
            messages.success(request, "缺少参数")
            return render(request, 'address.html')
        if not re.match(r'^[a-zA-Z0-9_]{5,10}$', username):
            messages.success(request, "用户名不符合要求")
            return render(request, 'address.html')
            # 判断手机号是否符合要求

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            messages.success(request, "密码须为8-20位")
            return render(request, 'address.html')

        if not re.match(r'^[0-9]{6}', postcode):
            messages.success(request, '邮编格式不符合要求')
            return render(request, 'address.html')

        try:
            address = Address.objects.create(receiver=username, mobile=mobile, place=place, detail_address=detail,
                                   postcode=postcode, user_id=request.user.id)

            if not request.user.default_address:
                request.user.default_address = address
                request.user.save()
        except DatabaseError:
            messages.success(request, "添加地址失败")
            return redirect(reverse('users:address'))

        messages.success(request, "添加地址成功")
        return redirect(reverse('users:address'))


class del_address(LoginRequiredMixin, View):
    """删除地址"""

    def get(self, request):
        # 将数据进行数据库对比
        ids = request.GET.get('id')
        address = Address.objects.get(id=ids)
        if not (address and request.user == address.user):
            return http.HttpResponseBadRequest("非法操作")
        # 将选中的id删除
        try:
            address.is_deleted = True
            address.save()
        except Exception as e:
            print(e, '=================================')
            messages.success(request, "删除失败")
            return redirect(reverse('users:address'))
        messages.success(request, "删除成功")
        return redirect(reverse('users:address'))

    def post(self, request):
        username = request.POST.get('username')
        mobile = request.POST.get('mobile')
        place = request.POST.get('address')
        detail = request.POST.get('detail')
        postcode = request.POST.get('portcode')
        if not all([username, mobile, place, detail]):
            messages.success(request, "缺少参数")
            return render(request, 'address.html')
        if not re.match(r'^[a-zA-Z0-9_]{5,10}$', username):
            messages.success(request, "用户名不符合要求")
            return render(request, 'address.html')
            # 判断手机号是否符合要求

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            messages.success(request, "密码须为8-20位")
            return render(request, 'address.html')

        if not re.match(r'^[0-9]{6}', postcode):
            messages.success(request, '邮编格式不符合要求')
            return render(request, 'address.html')

        try:
            Address.objects.update(receiver=username, mobile=mobile, place=place, detail_address=detail,
                                   postcode=postcode, user_id=request.user.id)
            messages.success(request, "修改成功")
            return redirect(reverse('users:address'))
        except Address.DoesNotExist as r:
            messages.success(request, "修改失败")
            return redirect(reverse('users:address'))



class My_Cart_View(View):
    """我的购物车"""

    def get(self, request):
        return render(request, 'cart.html')


class My_orderq(LoginRequiredMixin, View):
    """我的订单"""
    def get(self, request, page_num):
        """提供我的订单页面"""
        user = request.user
        # 查询订单
        orders = user.orderinfo_set.all().order_by("-create_time")

        # 遍历所有订单
        for order in orders:

            # 绑定订单状态
            order.status_name = OrderInfo.ORDER_STATUS_CHOICES[order.status - 1][1]
            # 绑定支付方式
            order.pay_method_name = OrderInfo.PAY_METHOD_CHOICES[order.pay_method - 1][1]
            order.sku_list = []
            # 查询订单商品
            order_goods = order.skus.all()
            # 遍历订单商品
            for order_good in order_goods:
                sku = order_good.sku
                sku.count = order_good.count
                sku.amount = sku.price * sku.count
                order.sku_list.append(sku)

        # 分页
        page_num = int(page_num)
        try:
            paginator = Paginator(orders, constants.ORDERS_LIST_LIMIT)
            page_orders = paginator.page(page_num)
            total_page = paginator.num_pages

        except EmptyPage:
            return http.HttpResponseNotFound('订单不存在')


        context = {
            "page_orders": page_orders,
            'total_page': total_page,
            'page_num': page_num,
            'username': request.user.username,
            'user_image': request.user.image
        }
        print(context)
        return render(request, "myorderq.html", context)


class My_prod(LoginRequiredMixin, View):
    """订单评价"""

    def get(self, request):
        context = {
            'username': request.user.username,
            'user_image': request.user.image
        }
        return render(request, "myprod.html", context=context)


class OrderCommentView(LoginRequiredMixin, View):
    """订单商品评价"""

    def get(self, request):
        """展示商品评价页面"""
        # 接收参数
        order_id = request.GET.get('order_id')
        # 校验参数
        try:
            OrderInfo.objects.get(order_id=order_id, user=request.user)
        except OrderInfo.DoesNotExist:
            return http.HttpResponseNotFound('订单不存在')

        # 查询订单中未被评价的商品信息
        uncomment_goods = OrderGoods.objects.filter(order_id=order_id, is_commented=False)
        if not uncomment_goods:
            return http.HttpResponseServerError('订单商品信息出错')

        # 构造待评价商品数据
        uncomment_goods_list = []
        for goods in uncomment_goods:
            uncomment_goods_list.append({
                'order_id': goods.order.order_id,
                'sku_id': goods.sku.id,
                'img': goods.sku.default_image,
                'name': goods.sku.name,
                'price': str(goods.price),
                'default_image_url': goods.sku.default_image,
                'comment': goods.comment,
                'comments': goods.sku.comments,
                'score': goods.score,
                'is_anonymous': str(goods.is_anonymous),
            })

        # 渲染模板
        context = {
            'uncomment_goods_list': uncomment_goods_list
        }
        print(context)
        return render(request, 'myprod.html', context)

    def post(self, request):
        """获取评价信息"""
        # 获取参数
        json_dict = json.loads(request.body.decode())
        comment = json_dict.get('comment')
        is_anonymous = json_dict.get('is_anonymous')
        order_id = json_dict.get('order_id')
        score = json_dict.get('score')
        sku_id = json_dict.get('sku_id')
        # 判断是否缺少参数
        if not all([comment, order_id, score, sku_id]):
            return http.HttpResponseBadRequest('缺少参数')
        # 判断这个订单是否是这个用户
        try:
            OrderInfo.objects.filter(order_id=order_id, user=request.user,
                                     status=OrderInfo.ORDER_STATUS_ENUM['UNCOMMENT'])
        except OrderInfo.DoesNotExist:
            return http.HttpResponseServerError('参数order_id错误')
        # 判断是否是这个商品
        try:
            order_goods = OrderGoods.objects.get(order_id=order_id, sku_id=sku_id, is_commented=False)
        except OrderGoods.DoesNotExist:
            return http.HttpResponseForbidden('参数sku_id有误')
        # 是否是布尔类型
        if is_anonymous and not isinstance(is_anonymous, bool):
            return http.HttpResponseForbidden("参数有误")
        # 保存订单商品数据
        order_goods.comment = comment
        order_goods.score = score
        order_goods.is_anonymous = is_anonymous
        order_goods.is_commented = True
        order_goods.save()

        # 累计评价数据
        order_goods.sku.comments += 1
        order_goods.sku.save()
        order_goods.sku.spu.comments += 1
        order_goods.sku.spu.save()

        # 如果所有订单都已评价， 则修改订单状态
        if OrderGoods.objects.filter(order_id=order_id, is_commented=False).count() == 0:
            OrderInfo.objects.filter(order_id=order_id).update(status=OrderInfo.ORDER_STATUS_ENUM['FINISHED'])
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '评价成功'})



class OrderDetail_View(View):
    """订单详情"""
    def get(self, request):
        order_id = request.GET.get('order_id')
        sku = request.GET.get('sku')
        order_ids = OrderInfo.objects.filter(order_id=order_id)
        order_goods = OrderGoods.objects.filter(order_id=order_id)


        for x in order_ids:
            print(x.total_amount)
            a = x.total_amount - 10

        context = {
            'username': request.user.username,
            'user_image': request.user.image,
            'order_id':order_ids,
            'order_goods': order_goods,
            'a': a,
        }
        return render(request, 'orderxq.html', context)


class Modify_Password_View(View):
    """找回密码"""

    def get(self, request):
        return render(request, 'modify_password.html')


def pcgetcaptcha(request):
    user_id = 'test'
    gt = GeetestLib(pc_geetest_id, pc_geetest_key)
    status = gt.pre_process(user_id)
    request.session[gt.GT_STATUS_SESSION_KEY] = status
    request.session["user_id"] = user_id
    response_str = gt.get_response_str()
    return HttpResponse(response_str)
